This vignette exemplifies how to use Spatial Annotations in SPATA2. It builds on the spatial annotations created in the vignette Creating Spatial Annotations for the glioblastoma samples UKF313T and UKF275T.
library(SPATA2)
library(tidyverse)
# exchange my/path/to with your directory
object_t313 <- loadSpataObject("my/path/to/object_UKF313T.RDS")
object_t275 <- loadSpataObject("my/path/to/object_UKF275T.RDS")
Spatial annotations annotate space which can be directly translated
into the image regardless of the annotation was drawn based on
histomorphological features (Image Annotations) or numeric and grouping
features (Numeric- and GroupAnnotations). The annotated space can be
used to obtain image sections cropped to only include the annotated
area. getSpatialAnnotation() extracts an object of class
SpatialAnnotation.
# obtain the IDs of all spatial annotations
getSpatAnnIds(object_t313)
## [1] "necrotic_area" "necrotic_center" "necrotic_edge" "necrotic_edge2"
necrotic_area <-
getSpatialAnnotation(
object = object_t313,
id = "necrotic_area",
add_image = T
)
# print summary
necrotic_area
## An object of class 'ImageAnnotation' named 'necrotic_area'. Tags: necrotic.
# print slot names
slotNames(necrotic_area)
## [1] "parent_name" "area" "id" "image" "image_info" "misc" "sample" "tags" "version"
By default, the image is cropped in a way that only the annotation is included.
# visualize from the SPATA2 object, with expand = 0
plotSpatialAnnotations(object_t313, ids = "necrotic_area", expand = 0, fill = NA)
# expand = 0 is how the image is extracted when extracting the spatial annotation
# (in SPATA2, images are plotted upside down to fit into the cartesian coordinate system)
plot(EBImage::flip(necrotic_area@image))
Fig.1 The image annotation ‘necrotic_area’ extracted as is.
The argument expand can be used with
getSpatialAnnotation(), too, in order to manipulate with
how much extra space the image is cropped. This works in pixel as well
as with SPATA2’s SI unit system.
# visualize from the SPATA2 object, with expand = 0
plotSpatialAnnotations(
object = object_t313,
ids = "necrotic_area",
expand = "500um",
fill = NA,
sb_dist = "500um",
sb_pos = c("4.5mm", "3mm")
)
necrotic_area_expanded <-
getSpatialAnnotation(
object = object_t313,
id = "necrotic_area",
add_image = T,
expand = "500um"
)
expanded_image <- EBImage::flip(necrotic_area_expanded@image)
plot(expanded_image)
Fig.2 The image annotation ‘necrotic_area’ extracted with a 500um buffer at each side.
The borders of spatial annotations can be used as reference points to analyze expression of numeric features (e.g. gene expression) as a function of distance to the annotated areas. The figure below illustrates the concept.
necrotic_ids <- c("necrotic_area", "necrotic_edge", "necrotic_edge2")
# obtain distance data relative to spatial annotations (SA) with getCoordsDfSA()
coords_df <-
getCoordsDfSA(object_t313, ids = necrotic_ids, unit = "mm", binwidth = "200um", core0 = T)
# add distance to necrosis as meta feature to the SPATA2 object
# to make them accessible for other functions
object_t313 <-
addFeatures(object_t313, feature_df = coords_df[,c("barcodes", "dist", "bins_dist")], overwrite = T)
# create ggproto layer for further surface plots
necrotic_outline <-
ggpLayerSpatAnnOutline(object_t313, ids = necrotic_ids, incl_edge = T, fill = "grey")
sas_screning <-
ggpLayerScreeningDirectionSAS(object_t313, ids = necrotic_ids, line_size = 0.75)
# show plots
plotImage(object_t313, outline = T) +
necrotic_outline +
sas_screning
plotSurface(object_t313, color_by = "dist", pt_clrsp = "plasma") +
necrotic_outline +
sas_screning +
labs(color = "Dist [mm]")
Fig. 3 Concept of illustrating expression as a function of distance.
Inferring expression as function of distance is part of the Spatial
Gradient Screening algorithm (SAS). Therefore, functions related to this
concept feature the acronym Sas such as
plotSasLineplot() or plotSasHeatmap().
plotSurface(object_t313, color_by = "HM_HYPOXIA", display_image = F, outline = T, pt_clrsp = "BuPu") +
necrotic_outline +
sas_screning
plotSasLineplot(object_t313, ids = necrotic_ids, variables = "HM_HYPOXIA", line_color = "blue") +
labs(x = "Distance to Necrotic Borders [mm]")
Fig.4 Visualizing HM_HYPOXIA expression as a function of distance to necrosis.
If the number of features displayed becomes too high for a lineplot
switch to plotSasHeatmap().
# use spatialAnnotationScreening() to identify non random genes
# and genes with specific expression pattern related to your spatial annotations
associated_with_necrosis <-
c("SLC2A1", "ADM", "ERO1A", "CD44", "STC2", "CA12", "VEGFA", "NDRG1", "TMEM158", "LOX")
repelled_by_necrosis <-
c("CD74", "CLU", "IFITM3", "C1QA", "C1QB", "CD68", "SELENOP", "SEC61B", "HLA-DRB1", "EMC6")
plotSasHeatmap(object_t313, variables = associated_with_necrosis, ids = necrotic_ids, clrsp = "BuPu") +
labs(x = "Distance to Necrotic Borders [mm]")
plotSasHeatmap(object_t313, variables = repelled_by_necrosis, ids = necrotic_ids, clrsp = "Reds 3") +
labs(x = "Distance to Necrotic Borders [mm]")
Fig.5 Visualizing gene expression as a function of distance via heatmaps.
The concept of Spatial Annotation Screening differentiates three types of areas when working with spatial annotations:
distance.By default distance is the maximum of distances between
the objects observations (here, barcoded spots) to their respective
closest annotation border. In the case of the three necrotic annotations
the maximum distance is approximately 2mm.
## in mm, since unit = "mm"
round(max(coords_df$dist), digits = 2)
## [1] 1.99
This is referred to as distance to edge (dte) as
observations up to the tissue’s edge are included. If your hypothesis
requires a specific distance parameter up to which the expression
gradient is inferred use the distance parameter. Fig.6
visualizes the differences in the set up.
sas_areas <- color_vector(clrp = "npg", names = c("core", "environment", "periphery"))
necrotic_outline_transp <-
ggpLayerSpatAnnOutline(object_t313, ids = necrotic_ids, incl_edge = T, fill = NA)
# rel_loc = location of each observation relative to the set up
plotSurface(coords_df, color_by = "rel_loc", clrp_adjust = sas_areas) +
necrotic_outline_transp +
labs(subtitle = "`distance` = 'dte'")
# the scenario changes when distance is specified
coords_df2 <-
getCoordsDfSA(object_t313, ids = necrotic_ids, distance = "1.5mm")
plotSurface(coords_df2, color_by = "rel_loc", clrp_adjust = sas_areas) +
necrotic_outline_transp +
labs(subtitle = "`distance` = 1.5mm")
Fig.7 Different set ups depending on the distance
parameter.
Another aspect to consider is the core parameter.
Depending on whether it is set to core = TRUE or
core = FALSE the inside of the annotation is included in
the gradient. It depends on the circumstances and your hypothesis
whether it makes sense to include the core or not. In case of the
necrotic areas we decided to set core = FALSE since we were
particularly interested in the reaction of the surrounding of the
necrotic areas. In other cases core = TRUE is suitable:
object_t275 <-
createNumericAnnotations(
object = object_t275,
variable = "HM_HYPOXIA",
threshold = "kmeans_high",
id = "hypoxic_ann",
overwrite = TRUE
)
signatures <- c("HM_HYPOXIA", "RCTM_TCR_SIGNALING")
horizon_layer <-
ggpLayerHorizonSAS(
object = object_t275,
id = "hypoxic_ann_1",
distance = "1.5mm",
line_size = 1,
line_type = "dotted"
)
hypoxic_outline <-
ggpLayerSpatAnnOutline(
object = object_t275,
ids = "hypoxic_ann_1",
line_size = 1.25
)
plotSurfaceComparison(object_t275, color_by = signatures, pt_clrsp = "red", normalize = T, display_image = F, ncol = 1) +
hypoxic_outline +
horizon_layer +
# use SI axes
ggpLayerAxesSI(object_t275, unit = "mm", breaks = str_c(c(2, 4, 6), "mm"))
plotSasLineplot(
object = object_t275,
variables = rev(signatures),
distance = "1.5mm",
core = TRUE,
line_color = "red",
line_size = 1.5,
border_linealpha = 1,
border_linecolor = "black",
border_linetype = "solid",
ncol = 1
) +
geom_vline(xintercept = 1.5, linetype = "dotted") +
labs(x = "Distance to Hypoxic Border [mm]")
Fig.8 An example where the inclusion of the core makes sense.